/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package reader;

import java.util.ArrayList;
import java.util.BitSet;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Vector;

/**
 *
 * @author Danzz
 */
public class Header {
    
    public String relation;
    public Map<String, DataType> attrib;
    public int idxClass;
    
    public ArrayList<String> attribString; // menyimpan nama atribut sesuai urutan baca
    
    
    public Header() {
        attrib = new LinkedHashMap<String, DataType>();
        attribString = new ArrayList<String>();
        this.relation="";
    }
    
    public void putRelation(String str) throws Exception {
        String parse1 = str.substring(("@RELATION").length());
        while (parse1.startsWith(" ")) {
            parse1 = parse1.replaceFirst(" ", "");
        }
        if (!parse1.startsWith("'") || !parse1.startsWith("\"")) {
            this.relation = parse1;
        } else if ((parse1.startsWith("'") && parse1.endsWith("'")) || (parse1.startsWith("\"") && parse1.endsWith("\""))) {
            this.relation = parse1.substring(1, parse1.length()-1);
        } else {
            throw new Exception("Relation kurang ' atau \""+" \""+str+"\"");
        }
    }
    
    public void readAtrribute(String attr) throws Exception {
        String parse1 = attr.substring(("@ATTRIBUTE").length());
        while (parse1.startsWith(" ")) {
            parse1 = parse1.replaceFirst(" ", "");
        }
        //get name
        int i=0;
        while (parse1.charAt(i)!=' ') {
            i++;
        }
        // name
        String name = parse1.substring(0, i);
        parse1 = parse1.substring(i);
        while (parse1.startsWith(" ")) {
            parse1 = parse1.replaceFirst(" ", "");
        }
        DataType dt = new DataType(parse1);
        attrib.put(name, dt);
        attribString.add(name);
        if (name.equalsIgnoreCase("class"))
            idxClass = attribString.indexOf(name);
    }
    
    public void readPertanyaan(String str) throws Exception {
        String parse1 = str.substring(("%%QUESTION").length());
        while (parse1.startsWith(" ")) {
            parse1 = parse1.replaceFirst(" ", "");
        }
        //get name
        int i=0;
        while (parse1.charAt(i)!=' ') {
            i++;
        }
        // name
        String name = parse1.substring(0, i);
        parse1 = parse1.substring(i);
        while (parse1.startsWith(" ")) {
            parse1 = parse1.replaceFirst(" ", "");
        }
        DataType dt = attrib.get(name);
        dt.putPertanyaan(parse1);
    }
    
    public int getNumAttribute() {
        return attrib.size();
    }
    
    public int getMaxJumlahValue() {
        int max = 0;
        for (Map.Entry<String, DataType> mEntry : attrib.entrySet()) {
            DataType dt = (DataType) mEntry.getValue();
            if (dt.getJumlahNominal()>max)
                max = dt.getJumlahNominal();
        }
        return max;
    }
    
    public int getMaxBit() {
        int max = this.getMaxJumlahValue();
        int n = 1;
        for (n=1;n<200;n++) {
            if (max<=Math.pow(2, n)) {
                if (max==Math.pow(2, n))
                    n++;
                break;
            }
        }
        
        return n;
    }
    
    public DataType getDataTypeFromIdx(int idx) {
        return attrib.get(attribString.get(idx));
    }
    
    public String getAttribValueAtIdx(int idxAttrib, int idxNominal){
        DataType dt = attrib.get(attribString.get(idxAttrib));
        return dt.getNominalAtIdx(idxNominal);
    }
    
    public Vector<Integer> getIndexAttribValue(Vector<String> vs) {
        Vector<Integer> vi = new Vector<Integer>();
        int idxString = 0;
        for (String v : vs) {
            vi.add(attrib.get(attribString.get(idxString)).getIndexNominalValue(v));
            idxString++;
        }
        return vi;
    }
    
    public String constructBitStringFromData(String data) {
        StringBuilder bs = new StringBuilder();
//      BitSet bs = new BitSet(this.getMaxJumlahValue()*this.getNumAttribute());
        
        //String[] contoh = ("xx,xx,xx,xx,xx,xx,xx,xx,priority").split(",");
        String[] contoh = data.split(",");
        Vector<String> contohData = new Vector<String>();
        for (String a : contoh) {
            contohData.add(a);
        }
        
        Vector<Integer> indexNominal = this.getIndexAttribValue(contohData);
        int idxNom = 0;
        int idxBit = 0;
        for (Integer a : indexNominal) {
            //System.out.println(contohData.get(idxNom)+"   "+a);
            //BitSet b = Data.intToBitSet(a, this.getMaxJumlahValue());
            String b = Data.intToBitString(a, this.getMaxBit());
            
            bs.append(b);
        }
        return bs.toString();
    }
    
    public ArrayList<String> constructValueFromBitString(String bs) {
        int maxValue = this.getMaxBit();
        ArrayList<String> ls = new ArrayList<String>();
        int idxAttrib = 0;
        for (int i = 0;i< maxValue*this.getNumAttribute();i+=maxValue) {
            ls.add(this.getAttribValueAtIdx(idxAttrib, Data.bitStringToInt(bs.substring(i, i+maxValue))));
            idxAttrib++;
        }
        return ls;
    }
    
    public String printAttribPertanyaan() {
        StringBuilder ret = new StringBuilder();
        for (Map.Entry<String, DataType> mEntry : attrib.entrySet()) {
            ret.append("Atribut : "+mEntry.getKey() + "  "+mEntry.getValue().toString());
            ret.append("\n");
            ret.append(((DataType)mEntry.getValue()).printPertanyaan());
            ret.append("\n");
        }
        return ret.toString();
    }
    
    @Override
    public String toString() {
        StringBuilder ret = new StringBuilder();
        for (Map.Entry<String, DataType> mEntry : attrib.entrySet()) {
            ret.append(mEntry.getKey());
            ret.append("     ");
            ret.append(mEntry.getValue().toString());
            ret.append("\n");
        }
        return ret.toString();
    }
    
}
